package com.stars.module.unit.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stars.base.constants.CommonNumberConstants;
import com.stars.base.constants.SystemConstants;
import com.stars.base.entity.CommonDTO;
import com.stars.base.entity.TreeNode;
import com.stars.base.exception.BaseException;
import com.stars.module.unit.entity.StarUnitEntity;
import com.stars.module.unit.mapper.StarUnitMapper;
import com.stars.module.unit.service.StarUnitService;
import com.stars.util.common.DevelopKit;
import com.stars.util.common.StringHelper;
import com.stars.util.tree.TreeNodeUtil;
import org.apache.poi.util.StringUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @author : mango
 * @version : 1.0
 * @date : 2022/10/31 11:20
 * @description : 部门服务接口实现类
 */
@Service
public class StarUnitServiceImpl implements StarUnitService {

    private final StarUnitMapper unitMapper;

    public StarUnitServiceImpl(StarUnitMapper unitMapper) {
        this.unitMapper = unitMapper;
    }

    //获取所有部门
    @Override
    public JSONObject loadUnitByFid(CommonDTO dto) {

        Page<StarUnitEntity> page = Page.of(dto.getCurrent(), dto.getPageSize());

        LambdaQueryWrapper<StarUnitEntity> wrapper = new LambdaQueryWrapper<>();

        wrapper.like(StarUnitEntity::getOrgName,dto.getSearch());
        wrapper.eq(StarUnitEntity::getFid, dto.getFid());
        wrapper.eq(StarUnitEntity::getIsUnit,1);

        wrapper.orderByAsc(StarUnitEntity::getShowOrder);

        JSONObject result = new JSONObject();

        Page<StarUnitEntity> systemDefineEntityPage = unitMapper.selectPage(page, wrapper);

        result.put("list",systemDefineEntityPage.getRecords());
        result.put("total",systemDefineEntityPage.getTotal());

        return result;
    }

    /**
     * @author : mango
     * @date : 2023/2/27 17:06
     * @description : 加载部门树
     */
    @Override
    public JSONArray loadAllUnit() {
        JSONArray array = new JSONArray();

        QueryWrapper<StarUnitEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("IS_UNIT",1);
        queryWrapper.orderByAsc("STEP");

        List<StarUnitEntity> allDeptArr = Optional.ofNullable(unitMapper.selectList(queryWrapper)).orElse(Collections.emptyList());

        List<TreeNode> treeNodes = new ArrayList<>();

        TreeNode root = null;

        for(StarUnitEntity dept : allDeptArr){

            if (SystemConstants.ROOT_UNITID.equals(dept.getId())) {
                root = new TreeNode(SystemConstants.ROOT_UNITID,dept.getOrgName(), CommonNumberConstants.MINUS_ONE_STR);
            }

            TreeNode node = new TreeNode();
            node.setValue(dept.getId());
            node.setpId(dept.getFid());
            node.setLabel(dept.getOrgName());

            treeNodes.add(node);
        }

        array.add(TreeNodeUtil.merge(root,treeNodes).toJSON());

        return array;
    }

    @Override
    public StarUnitEntity loadUnitById(String unitId) {
        return unitMapper.selectById(unitId);
    }

    @Override
    public boolean saveOrUpdateUnit(StarUnitEntity unit) throws BaseException {
        boolean result;

        if(StringUtils.hasLength(unit.getId())){
            //有ID，更新
            result = unitMapper.updateById(unit) > 0;
        }else{
            //无ID，新增
            String unitId = DevelopKit.generateUUID();
            unit.setId(unitId);

            unit.setStep(getMaxStep(unit.getFid()));
            unit.setIsUnit("1");
            unit.setUnitId(unitId);
            DevelopKit.setBaseInfo(unit);

            result = unitMapper.insert(unit) > 0;
        }
        return result;
    }

    @Override
    public boolean removeDept(String id) {
        LambdaQueryWrapper<StarUnitEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StarUnitEntity::getFid,id);


        if(unitMapper.exists(wrapper)){
            return false;
        }
        return unitMapper.deleteById(id)>0;
    }

    private String getMaxStep(String fid) throws BaseException {
        LambdaQueryWrapper<StarUnitEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(StarUnitEntity::getId,fid);
        queryWrapper.select(StarUnitEntity::getStep);
        StarUnitEntity result = unitMapper.selectOne(queryWrapper);

        if (result == null){
            throw new BaseException("无有效上级");
        }

        String fstep = result.getStep();
        String step;
        if(StringUtil.isBlank(fstep)){
            step = "";
        }else{
            step = result.getStep()+"____";
        }

        QueryWrapper<StarUnitEntity> wrapper = new QueryWrapper<>();
        wrapper.like("STEP",step);
        wrapper.select("MAX(STEP) AS STEP");
        StarUnitEntity starDept = unitMapper.selectOne(wrapper);

        String maxSonStep = starDept == null ? "" : starDept.getStep();

        Integer intPos = 1;
        if (StringUtils.hasLength(maxSonStep)) {
            String strStep = maxSonStep.substring(maxSonStep.length() - 4);
            intPos = Integer.parseInt(strStep) + 1;
        }
        return fstep + StringHelper.padLeft(String.valueOf(intPos), 4, '0');
    }

    @Override
    public Integer getMaxIndex(String fid) {
        QueryWrapper<StarUnitEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(StarUnitEntity::getFid,fid);
        queryWrapper.select("MAX(SHOWORDER) AS SHOWORDER");
        queryWrapper.eq("IS_UNIT",1);
        StarUnitEntity starDept = unitMapper.selectOne(queryWrapper);
        return starDept!=null?starDept.getShowOrder():0;
    }

    /**
     * 获取根机构信息
     * @return JSONObject
     */
    @Override
    public JSONObject getUnitRoot() {
        JSONObject object = new JSONObject();
        object.put("rootId",SystemConstants.ROOT_UNITID);
        return object;
    }
}
